package exteditapp;

import java.awt.Desktop;
import java.io.File;

/**
 * Application starter.
 * 
 * Starts in separated thread and stays in idle until process will be closed. Application startup
 * should work on all platforms, for which Java Runtime.open()/edit() functions made. For windows
 * platform uses customized functionality, which in addition allows user to select application,
 * with which file will be opened.
 * @author Arturas Smorgun, arturas@smorgun.lt
 * @version 2009.04.22
 */

public class AppStarter implements Runnable {
	
	/**
	 * Process which we start and watch for
	 */
	protected Process process;

	/**
	 * Name of file, which we want to open
	 */
	protected String fileName = null;
	
	
	/**
	 * Default constructor
	 */
	public AppStarter(){
	}
	
	/**
	 * Class constructor, also sets working file name
	 * @param fileName working file name
	 */
	public AppStarter (String fileName){
		this.fileName = fileName;
	}
	
	/**
	 * Launches application for a working file. Returns an error message if working file was not
	 * set on class construction process.
	 * @return true/false - sign if external application was started or not
	 */
	public boolean launch(){
		if(this.fileName == null)
			return false;
		return this.launch(this.fileName);
	}
	
	/**
	 * Launches application for a file. Allows to choose which file to process.
	 * Uses special functionality for Windows platform (which is not available on others).
	 * In case if platform is not windows - try to open predefined application for given file.
	 * Only if none of them worked - returns error message.
	 * @param fileName working file name (this file will be opened)
	 */
	public boolean launch(String fileName) {
		String osName = System.getProperty("os.name");
		if(osName.contains("Windows")){
			try{
				Runtime.getRuntime().exec("RUNDLL32.EXE SHELL32.DLL,OpenAs_RunDLL "+this.fileName);
				return true;
			}
			catch(Exception e){
				return this.openPredefined();
			}
		}
		else{
			return this.openPredefined();
		}
	}
	
	/**
	 * Same as {@link #launch()}, but used for concurrent execution (starting opening procedure in
	 * another thread).
	 */
	public void run(){
		this.launch();
	}
	
	/**
	 * Tries to open file for editing and then for viewing.
	 * Should work on all platforms supported by Java.
	 * @return true/false - was application started or not
	 */
	protected boolean openPredefined(){
		try{
			Desktop.getDesktop().edit(new File(this.fileName));
			return true;
		}
		catch(Exception e){
			try{
				Desktop.getDesktop().open(new File(this.fileName));
				return true;
			}
			catch(Exception e2){
				return false;
			}
		}
	}
	
}
